package com.campus.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.shop.common.ConstantProperties;
import com.campus.shop.common.Errors;
import com.campus.shop.controller.web.vo.*;
import com.campus.shop.entity.Order;
import com.campus.shop.entity.OrderCarts;
import com.campus.shop.entity.User;
import com.campus.shop.exception.ServiceException;
import com.campus.shop.mapper.*;
import com.campus.shop.service.OrderCartsService;
import com.campus.shop.service.OrderService;
import com.campus.shop.utils.ToolUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 统一订单（支付服务）日志表 服务实现类
 * @author xr
 * @since 2024-01-24 10:23:52
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private ShopCartMapper shopCartMapper;
    @Resource
    private OrderCartsService orderCartsService;

    /**
     * 创建订单
     * @param orderFormVo
     * @param userId
     * @return
     */
    @Resource
    private GoodsMapper goodsMapper;
    @Override
    @Transactional
    public HashMap<String, Object> createOrder(OrderFormVo orderFormVo, Integer userId) {
        try{
            Order order;
            if(orderFormVo.getType() == 1){
                 order = settlePay(orderFormVo, userId);
            }else{
                 order = cartPay(orderFormVo, userId);
            }
            HashMap<String, Object> map = new HashMap<>();
            map.put("totalMoney", order.getRealMoney()/100);
            map.put("orderNo", order.getOrderNo());
            return map;
        }catch (Exception e){
            log.info(e.getMessage());
            throw new ServiceException(Errors.ORDER_CREATE_FAIL);
        }
    }

    //购物车购买
    public Order settlePay(OrderFormVo orderFormVo, Integer userId){
        Integer[] ids = ToolUtils.stringToArray(orderFormVo.getIds());
        List<GoodsCartVo> cartList = shopCartMapper.getCartListById(ids, userId);
        BigDecimal totalPrice = cartList.stream()
                .map(item -> item.getGoodsPrice().multiply(BigDecimal.valueOf(item.getGoodsNum())))
                .reduce(BigDecimal::add)
                .orElse(BigDecimal.ZERO);
        Order order = insertOrder(userId, totalPrice, orderFormVo.getAddressId(), 1);
        for (Integer id :ids){
            OrderCarts orderCarts = new OrderCarts();
            orderCarts.setOrderId(order.getId());
            orderCarts.setCartId(id);
            orderCartsService.save(orderCarts);
        }
        shopCartMapper.changePayStatus(ids,ConstantProperties.cartPaying);
        return order;
    }
    //立即购买
    public Order cartPay(OrderFormVo orderFormVo, Integer userId){
        GoodsDetailVo goodInfo = goodsMapper.findGoodById(Integer.valueOf(orderFormVo.getIds()));
        Order order = insertOrder(userId,goodInfo.getPrice(),orderFormVo.getAddressId(),2);
        return order;
    }
    /**
     * 创建订单
     * @param userId
     * @param totalPrice
     * @param addressId
     */
    @Override
    public Order insertOrder(Integer userId, BigDecimal totalPrice, Integer addressId,Integer payType){
        String orderNo = createOrderNo(userId);
        Order order = new Order();
        order.setOrderNo(orderNo);
        order.setPayType(payType);
        order.setStatus(ConstantProperties.payWaiting);
        order.setCreateTime(System.currentTimeMillis()/1000);
        Integer realMoney = totalPrice.multiply(BigDecimal.valueOf(100)).intValue();;
        order.setRealMoney(realMoney);
        order.setUserId(userId);
        order.setAddressId(addressId);
        save(order);
        return order;
    }

    /**
     * 获取订单信息
     * @param orderNo
     * @param userId
     * @return
     */
    @Override
    public OrderInfoVo getOrderInfo(String orderNo, Integer userId) {
        OrderInfoVo orderInfo = orderMapper.getOrderInfo(orderNo, userId, ConstantProperties.payWaiting);
        int realMoney = orderInfo.getRealMoney() / 100;
        orderInfo.setSumPrice(new BigDecimal(realMoney).setScale(2, RoundingMode.HALF_UP));
        return orderInfo;
    }

    /**
     * 创建订单号
     * @param userId string 用户编号
     * @return string
     */
    public String createOrderNo(Integer userId)
    {
        //时间（精确到毫秒）
        DateTimeFormatter ofPattern = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String localDate = LocalDateTime.now().format(ofPattern);
        //3位随机数
        String randomNumeric = RandomStringUtils.randomNumeric(3);
        //5位用户id
        int subStrLength = 5;
        String sUserId = userId.toString();
        int length = sUserId.length();
        String str;
        if (length >= subStrLength) {
            str = sUserId.substring(length - subStrLength, length);
        } else {
            str = String.format("%0" + subStrLength + "d", userId);
        }
        String orderNum = localDate + randomNumeric + str;
        log.info("订单号:{}", orderNum);
        return orderNum;
    }

    /**
     * 预支付
     * @param way
     * @param orderNo
     * @return
     */
    @Override
    public void prePay(Integer way, String orderNo, Integer userId) {
        switch(way) {
            case ConstantProperties.aliPay:
            case ConstantProperties.wxPay:
                throw new ServiceException(Errors.PAY_METHOD_CLOSE);
            case ConstantProperties.balancePay:
                this.balancePay(orderNo, userId);
                return;
            default:
                throw new ServiceException(Errors.PAY_WAY_ERROR);
        }
    }

    /**
     * 余额支付
     * @param orderNo
     * @param userId
     * @return
     */
    @Resource
    private UserMapper userMapper;
    @Resource
    private OrderCartsMapper orderCartsMapper;
    @Transactional
    public Boolean balancePay(String orderNo, Integer userId){
        QueryWrapper<Order> query = new QueryWrapper<>();
        query.eq("order_no", orderNo);
        query.eq("user_id", userId);
        Order order = orderMapper.selectOne(query);
        if(order.getStatus() != ConstantProperties.payWaiting){
            throw new ServiceException(Errors.PAY_STATUS_ERROR);
        }
        BigDecimal payMoney = new BigDecimal(order.getRealMoney() / 100);
        User user = userMapper.selectById(userId);
        BigDecimal accountMoney = user.getAccountMoney();
        if(accountMoney.compareTo(payMoney) < 0){
            throw new ServiceException(Errors.BALANCE_PAY_ERROR);
        }
        BigDecimal balance_money = accountMoney.subtract(payMoney);
        user.setAccountMoney(balance_money);
        userMapper.updateById(user);//更新余额
        order.setStatus(ConstantProperties.paySuccess);//更新订单状态
        order.setUpdateTime(System.currentTimeMillis()/1000);
        saveOrUpdate(order);//保存
        QueryWrapper<OrderCarts> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id",order.getId());
        List<OrderCarts> cartsList = orderCartsMapper.selectList(wrapper);
        List<Integer> ids = cartsList.stream()
                .map(OrderCarts::getId) // 获取所有ID
                .collect(Collectors.toList());
        shopCartMapper.updateBatchByIds(ids,ConstantProperties.cartPaySuccess);
        return true;
    }

    /**
     * 获取订单状态数目
     * @param userId
     * @return
     */
    @Override
    public List<OrderStatusVo> getOrderList(Integer userId) {
        List<OrderStatusVo> list = orderMapper.selectOrderStatusCount(userId);
        for (OrderStatusVo orderStatusVo : list){

            orderStatusVo.setStatusIntro();
        }
        return list;
    }
}

